package org.report4service.utils;

import javax.microedition.lcdui.Font;
import javax.microedition.lcdui.Graphics;
import org.report4service.model.Report;

/**
 * Utility to display the monthly report
 * 
 * @author Jmpango
 * 
 */
public class MonthReportUtil {

    private static final String[] REPORT_LABELS = new String[] {
	    "Bks", "Bro", "Mag", "Hrs", "RVists"
    };

    private int month;
    private int year;
    
    /** cell padding */
    private static final short cellPadding = 1;
    private static final short DOUBLE_CELL_PADDING = 2 * cellPadding;

    /** starting week day: 0 for Monday, 6 for Sunday */
    private final short startWeekday = 0;

    /** cells border properties */
    private static final int borderWidth = 1;
    private static final int borderColor = 0x4080c1;

    /** report labels properties */
    private Font reportLabelFont = Font.getFont(Font.FACE_SYSTEM, Font.STYLE_BOLD,
	    Font.SIZE_MEDIUM);
    private int reportLabelBgColor = 0x4080c1;
    private int reportLabelColor = 0xffffff;
    private int reportLabelHeight = 0;

    /** header (month-report label) properties */
    private Font headerFont = Font
	    .getFont(Font.FACE_PROPORTIONAL, Font.STYLE_BOLD, Font.SIZE_LARGE);
    private int headerColor = 0x000000;
    private int headerHeight = 0;

    /** cells properties */
    private int foreColor = 0x000000;
    private int bgColor = 0xffffff;
    private int cellWidth = 0;
    private int cellHeight = 0;

    /** time properties */
    private int rows = 3;

    /** table properties */
    private int tableWidth = 0;
    private int tableHeight = 0;

    /** default screen measurements */
    private int getWidth = 0;
    private int getHeight = 0;

    private Report report;

    public MonthReportUtil(int month, int year, int getWidth, int getHeight, Report report) {
	setMonth(month);
	setYear(year);
        setReport(report);

	this.getWidth = getWidth;
	this.getHeight = getHeight;
	initializeMonthReport();
    }

    /**
     * initialize the monthReport
     */
    public void initializeMonthReport() {
	this.cellWidth = (getWidth - 15) / 5 + 2 * cellPadding;
	this.cellHeight = getHeight / 11 + 2 * cellPadding;

	this.headerHeight = headerFont.stringWidth("MM") + DOUBLE_CELL_PADDING;
	this.reportLabelHeight = reportLabelFont.getHeight() + DOUBLE_CELL_PADDING;

	this.tableWidth = (short) (5 * (cellWidth + borderWidth) + borderWidth);
	this.tableHeight = headerHeight + reportLabelHeight +
		this.rows * (cellHeight + borderWidth) + borderWidth;
    }

    public void paint(Graphics g) {
	// painting background
	g.setColor(bgColor);
	g.fillRect(0, 0, tableWidth, tableHeight);

	// painting header (month-report label)
	g.setFont(headerFont);
	g.setColor(headerColor);
	g.drawString("Report for " + getMonthName(getMonth()) + TextPool.EMPTY_STRING() + getYear(),
		tableWidth / 2, cellPadding, Graphics.TOP | Graphics.HCENTER);

	// painting report labels
	g.translate(0, headerHeight);

	g.setColor(reportLabelBgColor);
	g.fillRect(0, 0, tableWidth, reportLabelHeight);

	g.setColor(reportLabelColor);
	g.setFont(reportLabelFont);

	for (int i = 0; i < 5; i++) {
	    g.drawString(REPORT_LABELS[(i + startWeekday) % 5],
		    borderWidth + i * (cellWidth + borderWidth) + cellWidth / 2,
			cellPadding,
			Graphics.TOP | Graphics.HCENTER
		    );
	}

	// painting cells borders
	g.translate(0, reportLabelHeight);

	g.setColor(borderColor);

	for (int i = 0; i <= rows; i++) {
	    if (i == 3)
		g.fillRect(0, i * (cellHeight + borderWidth), tableWidth, borderWidth);
	}

	for (int i = 0; i <= 5; i++) {
	    g.fillRect(i * (cellWidth + borderWidth), 0, borderWidth, tableHeight - headerHeight
		    - reportLabelHeight);
	}

	g.setColor(foreColor);
	
	/* books*/
        int book = (report.getBook() > 0)? report.getBook():0;
	g.drawString(TextPool.EMPTY_STRING() + book, getColumn(0), getRow(1), Graphics.TOP | Graphics.HCENTER);
	
	/* bro*/
        int bro = (report.getBrochures() > 0)? report.getBrochures():0;
	g.drawString(TextPool.EMPTY_STRING() + bro, getColumn(1), getRow(1), Graphics.TOP | Graphics.HCENTER);
	
	/* mags*/
        int mag = (report.getMagazines() > 0)? report.getMagazines():0;
	g.drawString(TextPool.EMPTY_STRING() + mag, getColumn(2), getRow(1), Graphics.TOP | Graphics.HCENTER);
	
	/* hrs*/
        int hr = ((report.getMinutes() > 0)? report.getMinutes():0) / 60;
	g.drawString(TextPool.EMPTY_STRING() + hr, getColumn(3), getRow(1), Graphics.TOP | Graphics.HCENTER);
	
	/* rVists*/
        int rv = (report.getReturnVisits() > 0)? report.getReturnVisits():0;
	g.drawString(TextPool.EMPTY_STRING() + rv, getColumn(4), getRow(1), Graphics.TOP | Graphics.HCENTER);
	
	g.translate(0, -headerHeight - reportLabelHeight);

    }

    private int getColumn(int x) {
	return borderWidth + x * (cellWidth + borderWidth) + cellWidth / 2;
    }

    private int getRow(int y) {
	return borderWidth + y * (cellHeight + borderWidth) + cellPadding;
    }

    private String getMonthName(int monthNo) {

	String month = TextPool.EMPTY_STRING();

	switch (monthNo) {
	case 1:
	    month = "Jan";
	    break;
	case 2:
	    month = "Feb";
	    break;
	case 3:
	    month = "March";
	    break;
	case 4:
	    month = "April";
	    break;
	case 5:
	    month = "May";
	    break;
	case 6:
	    month = "June";
	    break;
	case 7:
	    month = "July";
	    break;
	case 8:
	    month = "August";
	    break;
	case 9:
	    month = "Sep";
	    break;
	case 10:
	    month = "Oct";
	    break;
	case 11:
	    month = "Nov";
	    break;
	case 12:
	    month = "Dec";
	    break;
	}

	return month;
    }

    /**
     * @return the monthYear
     */
    public int getMonth() {
	return month;
    }

    /**
     * @param monthYear
     *            the monthYear to set
     */
    public void setMonth(int month) {
	this.month = month;
    }

    /**
     * @return the year
     */
    public int getYear() {
	return year;
    }

    /**
     * @param year
     *            the year to set
     */
    public void setYear(int year) {
	this.year = year;
    }

    public Report getReport() {
        return report;
    }

    public void setReport(Report report) {
        this.report = report;
    }

}
